package com.priox.sigar.jsf;

import com.mm.support.mapper.DTOMapperService;
import com.priox.sigar.application.cliente.RegistroClienteApp;
import com.priox.sigar.application.mappers.ClienteMapper;
import com.priox.sigar.application.mappers.GrupoEmpresarialMapper;
import com.priox.sigar.application.mappers.SociedadMapper;
import com.priox.sigar.client.dto.ClienteDTO;
import com.priox.sigar.client.dto.ClienteSociedadDTO;
import com.priox.sigar.client.dto.GrupoEmpresarialDTO;
import com.priox.sigar.client.dto.SociedadDTO;
import com.priox.sigar.client.flt.ClienteFlt;
import com.priox.sigar.client.flt.SociedadFlt;
import com.priox.sigar.domain.model.Cliente;
import com.priox.sigar.domain.model.ClienteSociedad;
import com.priox.sigar.domain.model.constantes.PathConstant;
import com.priox.sigar.enums.ActivoInactivo;
import com.priox.sigar.jsf.util.FindCrudBeanBase;
import com.priox.sigar.server.infrastructure.persistence.exception.ApplicationException;
import com.priox.sigar.util.FileUtil;
import com.priox.sigar.util.TimeObserver;
import org.primefaces.component.inputtext.InputText;
import org.primefaces.event.CloseEvent;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.RowEditEvent;
import org.primefaces.event.SelectEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.event.ActionEvent;
import javax.faces.event.AjaxBehaviorEvent;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;


@ManagedBean
@Scope("session")
@Component
public class MaestroClienteJsfBean extends FindCrudBeanBase {

    private static final Logger LOG = LoggerFactory.getLogger(MaestroClienteJsfBean.class);

    ClienteFlt filtroBusqueda;
    SociedadFlt filtroPick;
    ClienteDTO nuevoRegistro;
    ClienteSociedadDTO nuevoRegistroDetalle;
    String archivoCarga;
    List<ClienteDTO> registros = new ArrayList<ClienteDTO>();
    List<SociedadDTO> detalle = new ArrayList<SociedadDTO>();
    List<SociedadDTO> detallePickList = new ArrayList<SociedadDTO>();

    List<GrupoEmpresarialDTO> cmbGrupoEmpresarial;
    List<SociedadDTO> cmbSociedad;


    @Autowired
    DTOMapperService mapperService;

    @Autowired
    GrupoEmpresarialMapper grupoEmpresarialMapper;

    @Autowired
    ClienteMapper clienteMapper;

    @Autowired
    SociedadMapper sociedadMapper;

    @Autowired
    RegistroClienteApp registroClienteApp;

    @Autowired
    private JobLauncher jobLauncher;


    @PostConstruct
    public void init() {
        filtroBusqueda = new ClienteFlt();
        nuevoRegistro = new ClienteDTO();
        cmbGrupoEmpresarial = grupoEmpresarialMapper.findAll();
//        findRegistros();
    }

    /*Métodos de herencia*/

    public void showNewDialogSeleccion(ActionEvent actionEvent) {
        filtroPick = new SociedadFlt();
        detallePickList = new ArrayList<SociedadDTO>();
    }

    @Override
    public void setCursorTableNull() {

    }

    public void onSelectDetail(SelectEvent actionEvent) {
        if (nuevoRegistro != null) {
            detalle = sociedadMapper.findBySociedadClienteId(nuevoRegistro.getClienteId());
        } else {
            detalle = new ArrayList<SociedadDTO>();
        }

    }

    public void onSelectGrupoEmpresarial(AjaxBehaviorEvent actionEvent) {
        if (filtroBusqueda.getGrupoEmpresarial() == null) {
            cmbSociedad = new ArrayList<SociedadDTO>();
        } else {
            cmbSociedad = sociedadMapper.findByGrupoEmpresarialId(filtroBusqueda.getGrupoEmpresarial().getGrupoEmpresarialId());
        }
    }

    @Override
    public void onNewRecord(ActionEvent actionEvent) {
        //To change body of implemented methods use File | Settings | File Templates.
        nuevoRegistro = new ClienteDTO();
        nuevoRegistro.setEstado(ActivoInactivo.ACTIVO);
        updateMode = false;
        InputText inputText = (InputText) findComponent("inputCodigo");
        inputText.setDisabled(false);

    }

    @Override
    public void onShowEditDialog(ActionEvent actionEvent) {
        setUpdateMode(true);
        setPersistMode(true);
        InputText inputText = (InputText) findComponent("inputCodigo");
        inputText.setDisabled(true);
        nuevoRegistro = registroClienteApp.findById(nuevoRegistro.getClienteId());
    }

    @Override
    public void onFind(ActionEvent actionEvent) {
        findRegistros();
    }

    public ActivoInactivo[] getAllEstado() {
        return ActivoInactivo.values();
    }


    public void findRegistros() {
        registros = clienteMapper.findByFilterDesc(filtroBusqueda);
        detalle = new ArrayList<SociedadDTO>();
        if (registros.size() == 0) {
            addMessage(noRecordFoundMsg, FacesMessage.SEVERITY_INFO);
            detalle = new ArrayList<SociedadDTO>();
        }
    }


    @Override
    public void onClean(ActionEvent actionEvent) {
        registros = new ArrayList<ClienteDTO>();
        detalle = new ArrayList<SociedadDTO>();
        nuevoRegistro = new ClienteDTO();
        filtroBusqueda = new ClienteFlt();
    }

    @Override
    public void onPersist(ActionEvent actionEvent) {
        Cliente cliente = mapperService.map(nuevoRegistro, Cliente.class);

        List<ClienteSociedadDTO> clienteSociedad= nuevoRegistro.getClienteSociedad();
        List<ClienteSociedad> clienteSociedadList= new ArrayList<ClienteSociedad>();

        for (ClienteSociedadDTO clienteSociedadDTO : clienteSociedad) {
            clienteSociedadList.add(mapperService.map(clienteSociedadDTO, ClienteSociedad.class));
        }
        registroClienteApp.save(cliente,clienteSociedadList,updateMode);
        findRegistros();
    }

    public void cleanActionSelect(ActionEvent actionEvent) {
        detallePickList = new ArrayList<SociedadDTO>();
        filtroPick = new SociedadFlt();
    }

    public void findActionSelect(ActionEvent actionEvent) {
        List<String> ids = new ArrayList<String>();
        for (ClienteSociedadDTO item : nuevoRegistro.getClienteSociedad()) {
            ids.add(item.getSociedadId());
        }
        filtroPick.setNotInSociedadList(ids);
        detallePickList = sociedadMapper.findByFilter(filtroPick);
        if (detallePickList.size() == 0) {
            addMessage(noRecordFoundMsg, FacesMessage.SEVERITY_INFO);
        }
    }

    public void seleccionar(ActionEvent actionEvent) {

        List<String> seleccionados = new ArrayList<String>();

        for (SociedadDTO item : detallePickList) {
            if (item.getSeleccionado() != null && item.getSeleccionado()) {
                seleccionados.add(item.getSociedadId());
            }
        }
        List<SociedadDTO> registros = registroClienteApp.findByIdList(seleccionados);

        for (SociedadDTO sociedadDTO : registros) {
            ClienteSociedadDTO clienteSociedadDTO = new ClienteSociedadDTO();
            clienteSociedadDTO.setSociedad(sociedadDTO);
            clienteSociedadDTO.setCliente(nuevoRegistro);
            nuevoRegistro.getClienteSociedad().add(clienteSociedadDTO);
        }
        String dialogName = (String) actionEvent.getComponent().getAttributes().get("dialogName");
        if (dialogName != null) {
            executeModal(dialogName, false);
        }
    }

    public void onModify(RowEditEvent event) {
        try {
            updateMode = true;
//            acreedorService.saveSimple(nuevoRegistro, updateMode);
            addMessage(successfullyUpdateMsg);
        } catch (ApplicationException e) {
            if (e.getCause() != null) {
                addMessage(e.getMessage(), FacesMessage.SEVERITY_INFO);
            } else {
                addMessage(e.getMessage(), FacesMessage.SEVERITY_WARN, e.getParameters());
                addMessage("No ha sido efectuado cambio alguno", FacesMessage.SEVERITY_INFO);
            }
        }

    }


    public void deleteDetailAction(ActionEvent actionEvent) {
        nuevoRegistro.getClienteSociedad().remove(nuevoRegistroDetalle);
    }

    @Override
    public void onDelete(ActionEvent actionEvent) {
        Cliente cliente = mapperService.map(nuevoRegistro, Cliente.class);
        registroClienteApp.delete(cliente);
        detalle = new ArrayList<SociedadDTO>();

    }

    @Override
    protected void onDialogClose(CloseEvent event) {
        nuevoRegistro = new ClienteDTO();
    }

    /*Getters and Setters*/

    public ClienteFlt getFiltroBusqueda() {
        return filtroBusqueda;
    }

    public void setFiltroBusqueda(ClienteFlt filtroBusqueda) {
        this.filtroBusqueda = filtroBusqueda;
    }

    public List<ClienteDTO> getRegistros() {
        return registros;
    }

    public void setRegistros(List<ClienteDTO> registros) {
        this.registros = registros;
    }

    public ClienteDTO getNuevoRegistro() {
        return nuevoRegistro;
    }

    public void setNuevoRegistro(ClienteDTO nuevoRegistro) {
        this.nuevoRegistro = nuevoRegistro;
    }

    public List<SociedadDTO> getDetalle() {
        return detalle;
    }

    public void setDetalle(List<SociedadDTO> detalle) {
        this.detalle = detalle;
    }

    public SociedadFlt getFiltroPick() {
        return filtroPick;
    }

    public void setFiltroPick(SociedadFlt filtroPick) {
        this.filtroPick = filtroPick;
    }

    public List<SociedadDTO> getDetallePickList() {
        return detallePickList;
    }

    public void setDetallePickList(List<SociedadDTO> detallePickList) {
        this.detallePickList = detallePickList;
    }


    public ClienteSociedadDTO getNuevoRegistroDetalle() {
        return nuevoRegistroDetalle;
    }

    public void setNuevoRegistroDetalle(ClienteSociedadDTO nuevoRegistroDetalle) {
        this.nuevoRegistroDetalle = nuevoRegistroDetalle;
    }

    public List<GrupoEmpresarialDTO> getCmbGrupoEmpresarial() {
        return cmbGrupoEmpresarial;
    }

    public void setCmbGrupoEmpresarial(List<GrupoEmpresarialDTO> cmbGrupoEmpresarial) {
        this.cmbGrupoEmpresarial = cmbGrupoEmpresarial;
    }

    public List<SociedadDTO> getCmbSociedad() {
        return cmbSociedad;
    }

    public void setCmbSociedad(List<SociedadDTO> cmbSociedad) {
        this.cmbSociedad = cmbSociedad;
    }
}
